package com.markyao.recos.conf;

import com.markyao.service.db.ConfigInfoService;
import com.markyao.service.raft.BroadcastConfigInfoService;
import com.markyao.utils.ResovleConfigUtils;
import com.markyao.vo.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

import static com.markyao.service.redis.UtilsKeys.*;

@Service
public class RecosConfServiceImpl implements RecosConfService{
    @Autowired
    @Qualifier("serviceConfMap")
    Map<String,Map<String,String>> serviceConfMap;

    private final List<String>pageList=new ArrayList<>();
    @Autowired
    @Qualifier("refreshConfAdviceSet")
    Map<String,Object> refreshConfAdviceSet;

    @Autowired
    @Qualifier("appsDataId")
    Map<String,Set<String>>appsDataId;
    @Autowired
    ConfigInfoService configInfoService;
    @Autowired
    BroadcastConfigInfoService broadcastConfigInfoService;
    @Override
    public Result autowiredConfig(String appName, String conf, String serverPort, String coname, HttpServletRequest request) {
        Map<String, String> map = serviceConfMap.getOrDefault(appName, new HashMap<>());
        if (!map.containsKey("appName")){
            pageList.add(appName);
        }
        map.put("appName",appName);
        map.put(CONF,conf);
        map.put(SERVERPORT,serverPort);
        map.put(CONAME,coname);
        map.put(REMOTEHOST,request.getRemoteHost());
        serviceConfMap.put(appName,map);
        return Result.success("注入配置成功!",null);
    }

    /**
     * 获取刷新配置事件类型: null 表示绑定配置类型，否则接收的是一个confInfo
     * @param appName
     * @return
     */
    @Override
    public Result getConfEvent(String appName) {
        if (refreshConfAdviceSet.containsKey(appName)) {
            Object obj = refreshConfAdviceSet.get(appName);
            if (obj==null){
                Map<String, String> map = serviceConfMap.getOrDefault(appName, new HashMap<>());
                return Result.success("1",map);
            }
            // TODO: 2023/9/8 扩展配置刷新类型，需要发送对应刷新键名-新值名过去
            if (obj instanceof ConfigInfoVo){
                ConfigInfoVo configInfoVo= (ConfigInfoVo) obj;
                Map<String, Object> map;
                if (ResovleConfigUtils.isYml(configInfoVo.getDataId())) {
                    map = ResovleConfigUtils.resovleYml(configInfoVo.getContent());
                }else {
                    map=ResovleConfigUtils.resovleProps(configInfoVo.getContent());
                }
                return Result.success("2",map);
            }
        }
        return Result.failed(500,"获取事件失败!注册信息不完整!");
    }

    @Override
    public Result getConfs(@RequestBody PageParams pageParams) {
        PageVo<Map> pageVo=new PageVo<>();
        List<Map>list=new ArrayList<>();

        pageVo.setList(list);
        pageVo.setTotal(Long.valueOf(serviceConfMap.size()));

        Integer currentPage = pageParams.getCurrentPage();
        Integer pageSize = pageParams.getPageSize();
        int start=(currentPage-1)*pageSize;
        int end=Math.min(start+pageSize,pageList.size());
        for (int i = start; i < end; i++) {
            String appName = pageList.get(i);
            Map<String, String> map = serviceConfMap.get(appName);
            list.add(map);
        }

        return Result.success(pageVo);
    }

    @Override
    public Result refreshConf(ConfParam conf) {
        //通知
        refreshConf(conf.getAppName(), null);
        //本地绑定配置注入
        Map<String, String> map = serviceConfMap.get(conf.getAppName());
        map.put(CONF,conf.getConfContent());
        // TODO: 2023/9/3 持久化
        serviceConfMap.put(conf.getAppName(),map);
        boolean f=broadcastConfigInfoService.refreshConf(conf);
        return Result.success("已通知客户端刷新配置!",null);
    }

    @Override
    public boolean refreshConf(String appName, Object obj) {
        refreshConfAdviceSet.put(appName,obj);
        return true;
    }

    @Override
    public Result refreshOk(String appName) {
        //需要清除掉刷新队列中的appName
        refreshConfAdviceSet.remove(appName);
        boolean f=broadcastConfigInfoService.refreshOk(appName);
        return Result.success("刷新成功!",null);
    }

    @Override
    public Result isRefresh(String appName) {
        boolean f = refreshConfAdviceSet.containsKey(appName);
        return Result.success(f);
    }

    @Override
    public Result getConfByDataIdAndGroupId(String dataId,String groupId) {
        Map<String,Object> result=configInfoService.selectByDataIdAndGroupId(dataId,groupId);
        if (result==null){
            return Result.failed(500,"未找到目标配置文件!");
        }
        return Result.success(result);
    }

    @Override
    public Result registDataIdAndAppName(String appName, String dataId) {
        Set<String> set = appsDataId.getOrDefault(dataId, new HashSet<>());
        set.add(appName);
        appsDataId.put(dataId,set);
        boolean f=broadcastConfigInfoService.registDataIdAndAppName(appName,dataId);
        return Result.success("注册成功!");
    }

    @Override
    public Result getBindConf(String appName) {
        Map<String, String> map = serviceConfMap.getOrDefault(appName, new HashMap<>());

        return Result.success("获取绑定配置信息成功",map);
    }
}
